package com.demo.connectdbtest.module.common.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author: Lmw
 * @date: 2019-12-17
 */
public class DateUtils {

    /**
     * 仅显示年月日，例如 2015-08-11.
     */
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    /**
     * 显示年月日时分秒，例如 2015-08-11 09:51:53.
     */
    public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final long ONE_MINUTE_MILLISECOND = 60*1000L;

    /**
     * 仅显示时分秒，例如 09:51:53.
     */
    public static final String TIME_FORMAT = "HH:mm:ss";

    public static final long ONE_HOUR_MILLISECOND = 60 * ONE_MINUTE_MILLISECOND;
    /**
     * 一天所对应的毫秒数
     */
    public static final long ONE_DAY_MILLISECOND = 24 * ONE_HOUR_MILLISECOND;
    /**
     * 一周所对应的毫秒数
     */
    public static final long ONE_WEEK_MILLISECOND = 7* ONE_DAY_MILLISECOND;
    public static final long ONE_MONTH_MILLISECOND = 30* ONE_DAY_MILLISECOND;
    public static final long ONE_YEAR_MILLISECOND = 365* ONE_DAY_MILLISECOND;

    /**
     * 每天的毫秒数 8640000.
     */
    public static final long MILLISECONDS_PER_DAY = 86400000L;

    /**
     * 每周的天数.
     */
    public static final long DAYS_PER_WEEK = 7L;

    /**
     * 每小时毫秒数.
     */
    public static final long MILLISECONDS_PER_HOUR = 3600000L;

    /**
     * 每分钟秒数.
     */
    public static final long SECONDS_PER_MINUTE = 60L;

    /**
     * 每小时秒数.
     */
    public static final long SECONDS_PER_HOUR = 3600L;

    /**
     * 每天秒数.
     */
    public static final long SECONDS_PER_DAY = 86400L;

    /**
     * 每个月秒数，默认每月30天.
     */
    public static final long SECONDS_PER_MONTH = 2592000L;

    /**
     * 每年秒数，默认每年365天.
     */
    public static final long SECONDS_PER_YEAR = 31536000L;

    /**
     * 常用的时间格式.
     */
    private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd",
            "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" };

    /**
     * 得到当前日期字符串.
     * @return String 日期字符串，例如2015-08-11
     * @since 1.0
     */
    public static String getDate() {
        return getDate(DateUtils.DATE_FORMAT);
    }

    /**
     * 得到当前时间字符串.
     * @return String 时间字符串，例如 09:51:53
     * @since 1.0
     */
    public static String getTime() {
        return formatDate(new Date(), DateUtils.TIME_FORMAT);
    }

    /**
     * 得到当前日期和时间字符串.
     * @return String 日期和时间字符串，例如 2015-08-11 09:51:53
     * @since 1.0
     */
    public static String getDateTime() {
        return formatDate(new Date(), DateUtils.DATETIME_FORMAT);
    }

    /**
     * 获取当前时间指定格式下的字符串.
     * @param pattern
     *            转化后时间展示的格式，例如"yyyy-MM-dd"，"yyyy-MM-dd HH:mm:ss"等
     * @return String 格式转换之后的时间字符串.
     * @since 1.0
     */
    public static String getDate(String pattern) {
        return DateFormatUtils.format(new Date(), pattern);
    }

    /**
     * 获取指定日期的字符串格式.
     * @param date  需要格式化的时间，不能为空
     * @param pattern 时间格式，例如"yyyy-MM-dd"，"yyyy-MM-dd HH:mm:ss"等
     * @return String 格式转换之后的时间字符串.
     * @since 1.0
     */
    public static String getDate(Date date, String pattern) {
        return DateFormatUtils.format(date, pattern);
    }

    /**
     * 获取日期时间字符串，默认格式为（yyyy-MM-dd）.
     * @param date 需要转化的日期时间
     * @param pattern 时间格式，例如"yyyy-MM-dd" "HH:mm:ss" "E"等
     * @return String 格式转换后的时间字符串
     * @since 1.0
     */
    public static String formatDate(Date date, Object... pattern) {
        String formatDate = null;
        if (pattern != null && pattern.length > 0) {
            formatDate = DateFormatUtils.format(date, pattern[0].toString());
        } else {
            formatDate = DateFormatUtils.format(date, DateUtils.DATE_FORMAT);
        }
        return formatDate;
    }

    /**
     * 获取当前年份字符串.
     * @return String 当前年份字符串，例如 2015
     * @since 1.0
     */
    public static String getYear() {
        return formatDate(new Date(), "yyyy");
    }

    /**
     * 获取当前月份字符串.
     * @return String 当前月份字符串，例如 08
     * @since 1.0
     */
    public static String getMonth() {
        return formatDate(new Date(), "MM");
    }

    /**
     * 获取当前天数字符串.
     * @return String 当前天数字符串，例如 11
     * @since 1.0
     */
    public static String getDay() {
        return formatDate(new Date(), "dd");
    }

    /**
     * 获取当前星期字符串.
     * @return String 当前星期字符串，例如星期二
     * @since 1.0
     */
    public static String getWeek() {
        return formatDate(new Date(), "E");
    }

    /**
     * 将日期型字符串转换为日期格式.
     * 支持的日期字符串格式包括"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
     * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm"
     * @param str
     * @return Date
     * @since 1.0
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return org.apache.commons.lang3.time.DateUtils.parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取当前日期与指定日期相隔的天数.
     * @param date 给定的日期
     * @return long 日期间隔天数，正数表示给定日期在当前日期之前，负数表示在当前日期之后
     * @since 1.0
     */
    public static long pastDays(Date date) {
        date = DateUtils.parseDate(DateUtils.formatDate(date, DateUtils.DATE_FORMAT));
        Date currentDate = DateUtils.parseDate(DateUtils.formatDate(new Date(), DateUtils.DATE_FORMAT));
        long t=0;
        if(date!=null&&currentDate!=null){
            t = (currentDate.getTime() - date.getTime()) / DateUtils.MILLISECONDS_PER_DAY;
        }
        return t;
    }

    /**
     * 将date的时间部分清零
     * @param day
     * @return 返回Day将时间部分清零后对应日期
     */
    public static Date getCleanDay( Date day ){
        return getCleanDay(getCalendar(day));
    }

    /**
     * 获取当前日期指定天数之后的日期.
     * @param num   相隔天数
     * @return Date 日期
     * @since 1.0
     */
    public static Date nextDay(int num) {
        Calendar curr = Calendar.getInstance();
        curr.set(Calendar.DAY_OF_MONTH, curr.get(Calendar.DAY_OF_MONTH) + num);
        return curr.getTime();
    }

    /**
     *
     * @param millis   增加毫秒数
     * @return Date 日期
     * @since 1.0
     */
    public static Date addSecond(long curMillis, long millis) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(curMillis+millis);
        return cal.getTime();
    }

    /**
     * 获取当前日期指定月数之后的日期.
     * @param num   间隔月数
     * @return Date 日期
     * @since 1.0
     */
    public static Date nextMonth(int num) {
        Calendar curr = Calendar.getInstance();
        curr.set(Calendar.MONTH, curr.get(Calendar.MONTH) + num);
        return curr.getTime();
    }

    /**
     * 获取当前日期指定年数之后的日期.
     * @param num    间隔年数
     * @return Date 日期
     * @since 1.0
     */
    public static Date nextYear(int num) {
        Calendar curr = Calendar.getInstance();
        curr.set(Calendar.YEAR, curr.get(Calendar.YEAR) + num);
        return curr.getTime();
    }


    /**
     * 计算两个日期之间相差天数.
     * @param start     计算开始日期
     * @param end       计算结束日期
     * @return long 相隔天数
     * @since 1.0
     */
    public static long getDaysBetween(Date start, Date end) {
        start = DateUtils.parseDate(DateUtils.formatDate(start, DateUtils.DATE_FORMAT));
        end = DateUtils.parseDate(DateUtils.formatDate(end, DateUtils.DATE_FORMAT));

        long diff=0;
        if(start!=null&&end!=null) {
            diff = (end.getTime() - start.getTime()) / DateUtils.MILLISECONDS_PER_DAY;
        }
        return diff;
    }

    /**
     * 计算两个日期之前相隔多少周.
     * @param start      计算开始时间
     * @param end    计算结束时间
     * @return long 相隔周数，向下取整
     * @since 1.0
     */
    public static long getWeeksBetween(Date start, Date end) {
        return getDaysBetween(start, end) / DateUtils.DAYS_PER_WEEK;
    }

    /**
     * 获取与指定日期间隔给定天数的日期.
     * @param specifiedDay    给定的字符串格式日期，支持的日期字符串格式包括"yyyy-MM-dd","yyyy-MM-dd HH:mm:ss",
     *            "yyyy-MM-dd HH:mm", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss",
     *            "yyyy/MM/dd HH:mm"
     * @param num   间隔天数
     * @return String 间隔指定天数之后的日期
     * @since 1.0
     */
    public static String getSpecifiedDayAfter(String specifiedDay, int num) {
        Date specifiedDate = parseDate(specifiedDay);
        Calendar c = Calendar.getInstance();
        c.setTime(specifiedDate);
        int day = c.get(Calendar.DATE);
        c.set(Calendar.DATE, day + num);
        String dayAfter = formatDate(c.getTime(), DateUtils.DATE_FORMAT);
        return dayAfter;
    }

    /**
     * 计算两个日期之前间隔的小时数.
     *
     * @param date1
     *            结束时间
     * @param date2
     *            开始时间
     * @return String 相差的小时数，保留一位小数
     * @since 1.0
     */
    public static String dateMinus(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return "0";
        }
        Long r = date1.getTime() - date2.getTime();
        DecimalFormat df = new DecimalFormat("#.0");
        double result = r * 1.0 / DateUtils.MILLISECONDS_PER_HOUR;
        return df.format(result);
    }

    /**
     * 获取当前季度 .
     *
     * @return Integer 当前季度数
     * @since 1.0
     */
    public static Integer getCurrentSeason() {
        Calendar calendar = Calendar.getInstance();
        Integer month = calendar.get(Calendar.MONTH) + 1;
        int season = 0;
        if (month >= 1 && month <= 3) {
            season = 1;
        } else if (month >= 4 && month <= 6) {
            season = 2;
        } else if (month >= 7 && month <= 9) {
            season = 3;
        } else if (month >= 10 && month <= 12) {
            season = 4;
        }
        return season;
    }

    /**
     * 将以秒为单位的时间转换为其他单位.
     *
     * @param seconds
     *            秒数
     * @return String 例如 16分钟前、2小时前、3天前、4月前、5年前等
     * @since 1.0
     */
    public static String getIntervalBySeconds(long seconds) {
        StringBuffer buffer = new StringBuffer();
        if (seconds < SECONDS_PER_MINUTE) {
            buffer.append(seconds).append("秒前");
        } else if (seconds < SECONDS_PER_HOUR) {
            buffer.append(seconds / SECONDS_PER_MINUTE).append("分钟前");
        } else if (seconds < SECONDS_PER_DAY) {
            buffer.append(seconds / SECONDS_PER_HOUR).append("小时前");
        } else if (seconds < SECONDS_PER_MONTH) {
            buffer.append(seconds / SECONDS_PER_DAY).append("天前");
        } else if (seconds < SECONDS_PER_YEAR) {
            buffer.append(seconds / SECONDS_PER_MONTH).append("月前");
        } else {
            buffer.append(seconds / DateUtils.SECONDS_PER_YEAR).append("年前");
        }
        return buffer.toString();
    }

    /**
     *
     * getNowTimeBefore(记录时间相当于目前多久之前)
     *
     * @param seconds
     *            秒
     * @return
     * @exception @since
     *                1.0
     * @author rlliu
     */
    public static String getNowTimeBefore(long seconds) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("上传于");
        if (seconds < 3600) {
            buffer.append((long) Math.floor(seconds / 60.0)).append("分钟前");
        } else if (seconds < 86400) {
            buffer.append((long) Math.floor(seconds / 3600.0)).append("小时前");
        } else if (seconds < 604800) {
            buffer.append((long) Math.floor(seconds / 86400.0)).append("天前");
        } else if (seconds < 2592000) {
            buffer.append((long) Math.floor(seconds / 604800.0)).append("周前");
        } else if (seconds < 31104000) {
            buffer.append((long) Math.floor(seconds / 2592000.0)).append("月前");
        } else {
            buffer.append((long) Math.floor(seconds / 31104000.0)).append("年前");
        }
        return buffer.toString();
    }

    /**
     *
     * getMonthsBetween(查询两个日期相隔的月份)
     *
     * @param startDate 开始日期1 (格式yyyy-MM-dd)
     * @param endDate   截止日期2 (格式yyyy-MM-dd)
     * @return
     */
    public static int getMonthsBetween(String startDate, String endDate) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(DateUtils.parseDate(startDate));
        c2.setTime(DateUtils.parseDate(endDate));
        int year = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
        int month = c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
        return Math.abs(year * 12 + month);
    }

    /**
     *
     * getDayOfWeek(获取当前日期是星期几)
     *
     * @param dateStr 日期
     * @return 星期几
     */
    public static String getDayOfWeek(String dateStr) {
        String[] weekOfDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        Date date = parseDate(dateStr);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int num = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        return weekOfDays[num];
    }

    /**
     * sns 格式 如几秒前，几分钟前，几小时前，几天前，几个月前，几年后， ... 精细，类如某个明星几秒钟之前发表了一篇微博
     *
     * @param createTime
     * @return
     */
    public static String snsFormat(long createTime) {
        long now = System.currentTimeMillis() / 1000;
        long differ = now - createTime / 1000;
        String dateStr = "";
        if (differ <= 60) {
            dateStr = "刚刚";
        } else if (differ <= 3600) {
            dateStr = (differ / 60) + "分钟前";
        } else if (differ <= 3600 * 24) {
            dateStr = (differ / 3600) + "小时前";
        } else if (differ <= 3600 * 24 * 30) {
            dateStr = (differ / (3600 * 24)) + "天前";
        } else {
            Date date = new Date(createTime);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            dateStr = sdf.format(date);
        }
        return dateStr;
    }

    /**
     * 得到UTC时间，类型为字符串，格式为"yyyy-MM-dd HH:mm"
     * 如果获取失败，返回null
     * @return
     */
    public static String getUTCTimeStr() {
        StringBuffer UTCTimeBuffer = new StringBuffer();
        Calendar cal = Calendar.getInstance() ;
        int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
        int dstOffset = cal.get(Calendar.DST_OFFSET);
        cal.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH)+1;
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        UTCTimeBuffer.append(year).append("-").append(month).append("-").append(day) ;
        UTCTimeBuffer.append(" ").append(hour).append(":").append(minute) ;
        try{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            sdf.parse(UTCTimeBuffer.toString()) ;
            return UTCTimeBuffer.toString() ;
        }catch(ParseException e)
        {
            e.printStackTrace() ;
        }
        return null ;
    }

    /**
     * 获取day对应的Calendar对象
     * @param day
     * @return 返回date对应的Calendar对象
     */
    public static Calendar getCalendar( Date day ){
        Calendar c = Calendar.getInstance();
        if( day != null)
            c.setTime(day);
        return c;
    }


    /**
     * 根据毫秒获得时间
     * @param millis
     * @return
     */
    public static Date getDate(long millis) {
        Calendar cal=Calendar.getInstance();
        cal.setTimeInMillis(millis);
        return cal.getTime();
    }

    /**
     * 根据毫秒获得时间字符串
     * @param millis
     * @return
     */
    public static String parseDate(long millis,String format) {
        Calendar cal=Calendar.getInstance();
        cal.setTimeInMillis(millis);
        return DateUtils.getDate(cal.getTime(),format);
    }

    /**
     * 字符串转时间
     * @param time
     * @param format
     * @return
     * @throws ParseException
     */
    public static Date stringToDate(String time, String format) throws ParseException {
        SimpleDateFormat sdf=new SimpleDateFormat(format);
        return sdf.parse(time);
    }

    /**
     * 字符串转毫秒
     * @param time
     * @param format
     * @return
     * @throws ParseException
     */
    public static long stringToMillis(String time, String format) throws ParseException {
        SimpleDateFormat sdf=new SimpleDateFormat(format);
        return sdf.parse(time).getTime();
    }

    public static Long getNowTime() {
        return System.currentTimeMillis();
    }

    public static String getTimeFormatByMillis(long millis) {
        String ret = millis + "秒";
        if (millis > 3600) {
            ret = (millis / 3600) + "小时" + ((millis / 60 - ((millis / 3600) * 60))) + "分钟" + (millis % 60) + "秒";
        } else if (millis > 60) {
            ret = ((millis / 60 - ((millis / 3600) * 60))) + "分钟" + (millis % 60) + "秒";
        }
        return ret;
    }

    /**
     * 获取某天所在周，返回如:2020#1
     * @param date
     * @return
     */
    public static String getWeekKey(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, -1);
        return c.getWeekYear() + "#" + c.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获取某天所在月，返回如:2020@1
     * @param date
     * @return 2020@1
     */
    public static String getMonthKey(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR) + "@" + (c.get(Calendar.MONTH) + 1);
    }

    /**
     * 获取两日期之间的全部日期
     *
     * @param beginStr
     * @param endStr
     * @return
     */
    public static List<String> getBetweenDates(String beginStr, String endStr) {
        return getBetweens(beginStr, endStr, DATE_FORMAT);
    }
    /**
     * 获取某日期的前几天
     *
     * @param endStr
     * @return
     */
    public static List<String> getBeforeDates(int beforeNum, String endStr) {
        return getBeforeDatesByNum(beforeNum,endStr, DATE_FORMAT);
    }
    public static List<String> getBeforeDatesByNum(int beforeNum, String endStr,String format ) {
        try {
            SimpleDateFormat sdf=new SimpleDateFormat(format);
            List<String> list = new ArrayList<String>();
            Long end = sdf.parse(endStr).getTime();

            Long oneDay = 1000 * 60 * 60 * 24l;
            Long time = end;
            for (int i = 0; i < beforeNum; i++) {
                Date date = new Date(time);
                if (time <= end && !list.contains(sdf.format(date)))
                    list.add(sdf.format(date));
                time -= oneDay;
            }

            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static List<String> getBetweens(String beginStr, String endStr,String format ) {
        try {
            SimpleDateFormat sdf=new SimpleDateFormat(format);
            List<String> list = new ArrayList<String>();
            Long now = new Date().getTime();
            Long begin = sdf.parse(beginStr).getTime();
            Long end = null;
            if (org.springframework.util.StringUtils.isEmpty(endStr)) {
                end = now;
            } else {
                end = sdf.parse(endStr).getTime();
            }
            Long oneDay = 1000 * 60 * 60 * 24l;
            if (end < begin) {//兼容开始结束反过来
                Long tmp = begin;
                begin = end;
                end = tmp;
            }

            Long time = begin;
            while (time <= end) {
                Date date = new Date(time);
                if (time < now && !list.contains(sdf.format(date))) list.add(sdf.format(date));
                time += oneDay;
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static boolean beforeForDateStr(String date1, String date2) throws ParseException {
        return DateUtils.beforeForDate(DateUtils.stringToDate(date1,DateUtils.DATE_FORMAT),
                DateUtils.stringToDate(date2,DateUtils.DATE_FORMAT));

    }
    /**
     * 当前日期所在星期的第一天00:00:00对应日期对象
     * @return 当前日期所在星期的第一天00:00:00对应日期对象
     */
    public static Date getFirstDayOfWeek() {
        return getFirstDayOfWeek( null );
    }

    /**
     * 日期date所在星期的第一天00:00:00对应日期对象
     * @param date
     * @return 日期所在星期的第一天00:00:00对应日期对象
     */
    public static Date getFirstDayOfWeek( Date date ) {
        return getFirstCleanDay( Calendar.DAY_OF_WEEK, date);
    }


    /**
     * 日期date所在月份的第一天00:00:00对应日期对象
     * @param date
     * @return 日期所在月份的第一天00:00:00对应日期对象
     */
    public static Date getFirstDayOfMonth(Date date) {
        return getFirstCleanDay(Calendar.DAY_OF_MONTH, date);
    }

    /**
     * 日期date所在月份的第一天的指定时间点对应的日期对象
     * @param date
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    public static Date getFirstDayOfMonth(Date date, int hour, int minute, int second) {
        Calendar c = Calendar.getInstance();
        if (date != null)
            c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, 1);
        return getSetTimeDay(c, hour, minute, second);
    }

    /**
     * 当前日期所在月份的第一天00:00:00对应日期对象
     * @return 当前日期所在月份的第一天00:00:00对应日期对象
     */
    public static Date getFirstDayOfMonth() {
        return getFirstDayOfMonth( null );
    }

    /**
     * 当前日期所在月份的最后一天00:00:00对应日期对象
     * @return 当前日期所在月份的最后一天00:00:00对应日期对象
     */
    public static Date getLastDayOfMonth() {
        return getLastDayOfMonth(null);
    }

    /**
     * 日期date所在月份的最后一天00:00:00对应日期对象
     * @param date
     * @return 日期date所在月份的最后一天00:00:00对应日期对象
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar c = getCalendar(getFirstDayOfMonth(date));
        c.add(Calendar.MONTH, 1);
        c.add(Calendar.DATE, -1);
        return getCleanDay(c);
    }

    public static boolean beforeForDate(Date date1,Date date2){
        return date1.before(date2);
    }

    /**
     * 获取某年某一周的第一天
     * @param year 某一年
     * @param weekOfYear 一年中第几天
     * @param weekOfDay 周几
     * @return
     */
    public static Date getDateOfWeek(int year, int weekOfYear, int weekOfDay) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.WEEK_OF_YEAR, weekOfYear);
        if(weekOfDay > 0) {
            c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        }
        return c.getTime();
    }

    /**
     * 计算N周后的日期
     * @param start 开始日期
     * @param weeks 可以为负，表示前N周
     * @return 新的日期
     */
    public static Date getDateAfterWeeks( Date start, int weeks ){
        return getDateAfterMs( start, weeks * ONE_WEEK_MILLISECOND );
    }

    /**
     * 计算N年后的日期
     * @param start 开始日期
     * @param years 可以为负，表示前N年
     * @return 新的日期
     */
    public static Date getDateAfterYears( Date start, int years ){
        return add( Calendar.YEAR, years, start );
    }


    /**
     * 计算N天后的日期（0点）
     * @param start
     * @param days
     * @return
     */
    public static Date getDateAfterDaysNoTime(Date start ,int days){
        Calendar cal = Calendar.getInstance();
        cal.setTime(getDateAfterDays(start, days));
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return  cal.getTime();
    }

    /**
     * 计算N天后的日期
     * @param start 开始日期
     * @param days 可以为负，表示前N天
     * @return 新的日期
     */
    public static Date getDateAfterDays( Date start, int days ){
        return getDateAfterMs( start, days * ONE_DAY_MILLISECOND );
    }

    /**
     * 计算N毫秒后的日期
     * @param start 开始日期
     * @param ms 可以为负，表示前N毫秒
     * @return 新的日期
     */
    public static Date getDateAfterMs( Date start, long ms ){
        return new Date( start.getTime() + ms );
    }

    private static Date add( int datePart, int detal, Date date ) {
        Calendar c = Calendar.getInstance();
        if( date != null )
            c.setTime( date );
        c.add( datePart,detal );
        return c.getTime();
    }

    private static Date getCleanDay(Calendar c) {
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.clear(Calendar.MINUTE);
        c.clear(Calendar.SECOND);
        c.clear(Calendar.MILLISECOND);
        return c.getTime();
    }

    private static Date getFirstCleanDay( int datePart, Date date ) {
        Calendar c = Calendar.getInstance();
        if( date != null )
            c.setTime( date );
        c.set( datePart,1 );
        return getCleanDay(c);
    }

    private static Date getSetTimeDay(Calendar c, int hour, int minute, int second) {
        c.set(Calendar.HOUR_OF_DAY, hour);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, second);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    /**
     * 日期格式 年 月 日 如2009-02-26
     */
    public static final String DATEFORMATDAY = "yyyy-MM-dd";

    public static Date parase(String string, String format) {
        if (StringUtils.isEmpty(string)) {
            return null;
        }
        try {
            return new SimpleDateFormat(format).parse(string);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 日期格式年 月 日 时 分 秒 毫秒 如2009-02-26 15:40:00 110
     */
    public static final String DATEFORMATMILLISECOND = "yyyy-MM-dd HH:mm:ss SSS";

    /**
     * 按指定的格式，把Date转换成String 如date为null,返回null
     *
     * @param date
     *            Date参数
     * @param format
     *            日期格式
     * @return String
     */
    public static String format(Date date, String format) {
        if (date == null) {
            return null;
        }
        return new SimpleDateFormat(format).format(date);
    }

    public static Date getDayLastTime(Date date) throws Exception {
        if (date == null) {
            return null;
        }
        final String str = format(date, DATEFORMATDAY) + " 23:59:59 999";
        return parase(str, DATEFORMATMILLISECOND);
    }


}

